$S.Menu = Ext.extend($S.ViewComponent,{
    hoverCls:'s-menuitem-hover',
    align:"r",
    constructor: function(config) {
        $S.Menu.superclass.constructor.call(this, config);
        this.align = config.align||this.align;
    },
    initComponent : function(config){
        $S.Menu.superclass.initComponent.call(this, config);
        Ext.getBody().insertFirst(this.wrap);
        this.initMenuElement();
    },
    initEvents : function(){
        $S.Button.superclass.initEvents.call(this);
        this.addEvents(
        /**
         * @event click
         * 鼠标点击事件.
         * @param {Spark.Menu} menu对象.
         * @param {String} mid mid.
         * @param {EventObject} e 键盘事件对象.
         */
        'click');
    },
    initMenuElement: function(){
        for(var key in this.map){
            var elid = this.map[key];
//            Ext.getBody().insertFirst(elid);
            Ext.get(elid).insertAfter(this.wrap)
        }
    },
    processListener: function(ou){
        $S.Menu.superclass.processListener.call(this, ou);
    },
    destroy : function(){
        $S.Menu.superclass.destroy.call(this);
        this.clearLisener();
    },
    onDocumentMouseOver: function(e){
        var menu = this.findTargetDom(e.target,'role','menu');
        if(!menu) return;
        if(Ext.fly(menu).contains(e.target)) {
            var menuItem = this.findTargetDom(e.target,'role','menuitem');
            this.hover(menu,menuItem);
        }        
    },
    isEventFromComponent:function(el){
        var v = $S.Menu.superclass.isEventFromComponent.call(this,el);
        if(!v) {
            for(var key in this.map){
                v = Ext.fly(this.map[key]).contains(el);
                if(v) return true;
            }
            Ext.each(this.child,function(id){
                var cmp = $(id);
                if(cmp && cmp.isEventFromComponent){
                    if(cmp.isEventFromComponent(el)){
                        v = true;
                        return true;
                    }
                }
            })
        }
        return v;
    },
    findTargetDom: function(target,type,value){
        var v = Ext.fly(target).getAttributeNS('',type);
        if(v==value) {
            return target;
        }else {
            var el = Ext.fly(target).parent('['+type+'='+value+']');
            return el&&el.dom;
        }
        
    },
    findHoverItem : function(el){
        return Ext.fly(el).child('div.'+ this.hoverCls);
    },
    hover: function(menu,menuItem){
        var hoverItem = this.findHoverItem(menu);
        if(hoverItem && menuItem == hoverItem.dom) return;
        this.unhover(menu);
        if(menuItem) {
            Ext.fly(menuItem).addClass(this.hoverCls);
            var mid = Ext.fly(menuItem).getAttributeNS('','mid');
            if(this.map[mid]){
                this.openSubMenu(menuItem,mid);
            }
            Ext.each(this.child,function(id){
                var cmp = $(id);
                if(cmp && cmp.collapse){
                    cmp.collapse()
                }
            })
        }
        
    },
    unhover: function(menu){
        var hoverItem = this.findHoverItem(menu);
        if(hoverItem) {
            Ext.fly(hoverItem).removeClass(this.hoverCls);
            var mid = Ext.fly(hoverItem).getAttributeNS('','mid');
            if(this.map[mid]){
                this.closeSubMenu(mid);
            }
        }
    },
    initLisener: function(){
        Ext.get(document.documentElement).on("mouseover", this.onDocumentMouseOver, this);
        Ext.get(document.documentElement).on("click", this.onDocumentClick, this);
    },
    clearLisener: function(){
        Ext.get(document.documentElement).un("mouseover", this.onDocumentMouseOver, this);
        Ext.get(document.documentElement).un("click", this.onDocumentClick, this);
    },
    onDocumentClick: function(e){
        var menuItem = this.findTargetDom(e.target,'role','menuitem');
        if(!menuItem) return;
        var mid = Ext.fly(menuItem).getAttributeNS('','mid');
        if(!this.map[mid]){
            this.fireEvent("click", this,mid, e);
            this.hide();
        }
    },
    openSubMenu: function(dom,id){
        var menuItem = Ext.get(dom),menu = Ext.get(this.map[id]);
        menu.dom.style.opacity=1;
//        menu.setDisplayed('block');
        this.syncSubMenu(menuItem,menu);
    },
    syncSubMenu : function(menuItem,menu){
        var vs = (Ext.isIE6 || Ext.isIE7) ? 2 : 0, 
            sl = document[Ext.isStrict&&!Ext.isWebKit?'documentElement':'body'].scrollLeft,
            st = document[Ext.isStrict&&!Ext.isWebKit?'documentElement':'body'].scrollTop,
            xy = menuItem.getXY(),_x = xy[0] - sl,_y = xy[1] - st,
            W=menu.getWidth(),H=menu.getHeight(),
            PH=menuItem.getHeight(),PW=menuItem.getWidth(),
            BH=$S.getViewportHeight()-3,BW=$S.getViewportWidth()-3,
            x = this.align == 'r' ? ((_x+W+PW)>BW ? (_x-W+vs):(_x+PW - vs)) : ((_x-W+vs)>0 ? (_x-W+vs) : (_x+PW - vs)),
            y = (_y+H)>BH ? (_y+PH-H) : _y;
        menu.setLeft(x+sl);
        menu.setTop(y+st);
    },
    closeSubMenu: function(id){
        var menu = Ext.get(this.map[id]);
        menu.dom.style.opacity=0;
        menu.moveTo(-10000,-10000);
//        menu.setDisplayed('none');
        this.unhover(menu);      
    },
    show: function(x,y){
        this.wrap.setLeft(x);
        this.wrap.setTop(y);
        this.wrap.dom.style.opacity=1;
//        this.wrap.setDisplayed('block');
        this.initLisener();
    },
    hide: function(){
        this.unhover(this.wrap);
        this.wrap.moveTo(-10000,-10000);
        this.wrap.dom.style.opacity=0;
//        this.wrap.setDisplayed('none');
        for(var key in this.map){
            var m = Ext.fly(this.map[key]);
            m.moveTo(-10000,-10000);
            m.dom.style.opacity=0;
//            m.setDisplayed('none');
        }
        this.clearLisener();
    }
})   